<!DOCTYPE html>
<html>

<head>
  <title>基于mobx的公共状态管理方案</title>
  <meta charset='utf-8'>
  <link href='https://cdn.maxiang.io/res-min/themes/marxico.css' rel='stylesheet'>
  <style>
    #preview-contents {
      margin-top: -20px;
      width: 1000px;
    }
  </style>
</head>

<body>
  <div id='preview-contents' class='note-content'>



    <h3 id="基于mobx的公共状态管理方案">基于mobx的公共状态管理方案</h3>

    <blockquote>
      <p><a href="https://cn.mobx.js.org/" target="_blank">https://cn.mobx.js.org/</a></p>

      <p>mobx是一个简单可扩展的状态管理库，相比较于redux，它：</p>

      <ul>
        <li>
          <p>开发难度低</p>
        </li>
        <li>
          <p>开发代码量少</p>
        </li>
        <li>
          <p>渲染性能好</p>
        </li>
      </ul>
    </blockquote>

    <p><img longdesc="./1671202548466.png" alt="Alt text" title="" type="image/png"
        src=""
        class=""></p>

    <p><strong>浏览器兼容性</strong> <br>
      MobX &gt;=5 版本运行在任何支持 ES6 proxy 的浏览器。 <br>
      MobX 4 可以运行在任何支持 ES5 的浏览器上，而且也将进行持续地维护。MobX 4 和 5 的 API 是相同的，并且语义上也能达到相同的效果。 <br>
      MobX 6 「最新版本」移除了装饰器的操作（因为装饰器不是JS标准规范）！</p>

    <p><strong>想要使用mobx，首先需要让项目支持JS装饰器语法！</strong></p>

    <blockquote>
      <p>$ yarn add <code>@babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties</code></p>
    </blockquote>

    <p>package.json</p>

    <pre class="prettyprint hljs-dark"><code class="hljs prolog"><div class="hljs-line"><span class="hljs-string">"babel"</span>: {
</div><div class="hljs-line">  <span class="hljs-string">"presets"</span>: [ <span class="hljs-string">"react-app"</span> ],
</div><div class="hljs-line">  <span class="hljs-string">"plugins"</span>: [
</div><div class="hljs-line">    [
</div><div class="hljs-line">      <span class="hljs-string">"@babel/plugin-proposal-decorators"</span>,
</div><div class="hljs-line">      {
</div><div class="hljs-line">        <span class="hljs-comment">/* legacy /ˈleɡəsi/：使用历史遗留（Stage-1）的装饰器中的语法和行为。它为提案从 Stage-1 到当前阶段 Stage-2 平稳过渡作铺垫*/</span>
</div><div class="hljs-line">        <span class="hljs-string">"legacy"</span>: true
</div><div class="hljs-line">      }
</div><div class="hljs-line">    ],
</div><div class="hljs-line">    [
</div><div class="hljs-line">       <span class="hljs-string">"@babel/plugin-proposal-class-properties"</span>,
</div><div class="hljs-line">       {
</div><div class="hljs-line">         <span class="hljs-comment">/* loose=false时，是使用Object.defineProperty定义属性，loose=ture，则使用赋值法直接定义 */</span>
</div><div class="hljs-line">         <span class="hljs-string">"loose"</span>: true
</div><div class="hljs-line">       }
</div><div class="hljs-line">     ]
</div><div class="hljs-line">  ]
</div><div class="hljs-line">}
</div></code></pre>

    <h4 id="mobx-第五代版本的运用">mobx 第五代版本的运用</h4>

    <p><strong>安装</strong></p>

    <blockquote>
      <p>$yarn add mobx@5 mobx-react@6</p>
    </blockquote>

    <p><strong>初窥mobx</strong> <br>
      实现一个简单的计数器累加效果</p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, action } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { observer } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx-react'</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">// 公共状态管理</span>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable num = <span class="hljs-number">10</span>;
</div><div class="hljs-line">    @action handle() {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.num++;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">//组件监听</span>
</div><div class="hljs-line">@observer
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Demo</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
</div><div class="hljs-line">    render() {
</div><div class="hljs-line">        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span>
</div><div class="hljs-line"><span class="xml">            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{store.num}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
</div><div class="hljs-line"><span class="xml">            <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
</div><div class="hljs-line"><span class="xml">            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> {</span>
</div><div class="hljs-line"><span class="xml">                store.handle();</span>
</div><div class="hljs-line"><span class="xml">            }}&gt;按钮<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</div><div class="hljs-line"><span class="xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">// 函数组件不支持装饰器，我们则基于observer把其执行即可</span>
</div><div class="hljs-line"><span class="hljs-comment">/* const Demo = observer(function Demo() {</span>
</div><div class="hljs-line"><span class="hljs-comment">    return &lt;div&gt;</span>
</div><div class="hljs-line"><span class="hljs-comment">        ...</span>
</div><div class="hljs-line"><span class="hljs-comment">    &lt;/div&gt;;</span>
</div><div class="hljs-line"><span class="hljs-comment">}); */</span>
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-keyword">const</span> root = ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));
</div><div class="hljs-line">root.render(
</div><div class="hljs-line">    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Demo</span> /&gt;</span></span>
</div><div class="hljs-line"><span class="xml">);</span>
</div></code></pre>

    <p><strong>observable</strong> <br>
      一个实现“监听值变化”的函数或者装饰器！ <br>
      先来看一个效果</p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, autorun } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    <span class="hljs-comment">// 只有基于 observable 装饰器修饰的属性，在可以在修改其值后，监测到它的变化</span>
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>;
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">// 监听用到的依赖，当依赖改变时会执行callback「最开始立即执行一次」</span>
</div><div class="hljs-line">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'autorun:'</span>, store.x);
</div><div class="hljs-line">});
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">// 一秒钟后改变内容</span>
</div><div class="hljs-line">setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    store.x = <span class="hljs-number">100</span>;
</div><div class="hljs-line">}, <span class="hljs-number">1000</span>);
</div></code></pre>

    <p>探索 observable 的原理</p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, observe } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">let</span> obj = observable({
</div><div class="hljs-line">    <span class="hljs-attr">x</span>: <span class="hljs-number">10</span>,
</div><div class="hljs-line">    <span class="hljs-attr">y</span>: <span class="hljs-number">20</span>
</div><div class="hljs-line">});
</div><div class="hljs-line"><span class="hljs-comment">// console.log(obj); //对象是经过ES6 Proxy做了劫持处理的</span>
</div><div class="hljs-line"><span class="hljs-comment">// observe:当监听的对象做出变化时，触发callback</span>
</div><div class="hljs-line">observe(obj, change =&gt; {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'内容改变了：'</span>, change);
</div><div class="hljs-line">});
</div><div class="hljs-line">obj.x = <span class="hljs-number">100</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">//----</span>
</div><div class="hljs-line"><span class="hljs-comment">// observable不能直接对原始值类型进行监听，需要基于.box处理</span>
</div><div class="hljs-line"><span class="hljs-keyword">let</span> x = observable.box(<span class="hljs-number">10</span>);
</div><div class="hljs-line">observe(x, change =&gt; {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'内容改变了：'</span>, change);
</div><div class="hljs-line">});
</div><div class="hljs-line"><span class="hljs-built_in">console</span>.log(x, x.get());
</div><div class="hljs-line">x.set(<span class="hljs-number">1000</span>);
</div></code></pre>

    <p>所以我们以后创建的公共状态信息，前面都要设置 <code>@observable</code> 装饰器！！</p>

    <p><strong>computed计算属性</strong></p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, autorun, computed, reaction } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>;
</div><div class="hljs-line">    @observable count = <span class="hljs-number">3</span>;
</div><div class="hljs-line">    @observable price = <span class="hljs-number">120</span>;
</div><div class="hljs-line">    <span class="hljs-comment">// 设置具备计算缓存的计算属性：依赖的状态值没有变化，方法不会重新执行，使用之前计算缓存的结果</span>
</div><div class="hljs-line">    @computed get total() {
</div><div class="hljs-line">        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'OK'</span>);
</div><div class="hljs-line">        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.count * <span class="hljs-keyword">this</span>.price;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'autorun:'</span>, store.total, store.x);
</div><div class="hljs-line">});
</div><div class="hljs-line"><span class="hljs-comment">// 相比较于autorun，提供更精细的管控「第一次不会触发」</span>
</div><div class="hljs-line">reaction(
</div><div class="hljs-line">    <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> [store.total, store.x],
</div><div class="hljs-line">    () =&gt; {
</div><div class="hljs-line">        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'reaction:'</span>, store.total, store.x);
</div><div class="hljs-line">    }
</div><div class="hljs-line">);
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    store.x = <span class="hljs-number">1000</span>;
</div><div class="hljs-line">    store.count = <span class="hljs-number">10</span>;
</div><div class="hljs-line">}, <span class="hljs-number">1000</span>);
</div></code></pre>

    <p><strong>action修改公共状态的方法</strong></p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, autorun, action, configure } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">// 设定只能基于action方法修改状态值</span>
</div><div class="hljs-line">configure({
</div><div class="hljs-line">    <span class="hljs-attr">enforceActions</span>: <span class="hljs-string">"observed"</span>
</div><div class="hljs-line">});
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>;
</div><div class="hljs-line">    @action changeX(val) {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.x = val;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'autorun:'</span>, store.x);
</div><div class="hljs-line">});
</div><div class="hljs-line">setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    store.changeX(<span class="hljs-number">1000</span>);
</div><div class="hljs-line">    <span class="hljs-comment">// store.x = 2000; //Uncaught Error: [mobx] Since strict-mode is enabled, changing observed observable values outside actions is not allowed.</span>
</div><div class="hljs-line">}, <span class="hljs-number">1000</span>);
</div></code></pre>

    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>;
</div><div class="hljs-line">    <span class="hljs-comment">// .bound确保this永远是实例</span>
</div><div class="hljs-line">    @action.bound changeX(val) {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.x = val;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line">...
</div><div class="hljs-line">setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-keyword">let</span> changeX = store.changeX;
</div><div class="hljs-line">    changeX(<span class="hljs-number">1000</span>);
</div><div class="hljs-line">}, <span class="hljs-number">1000</span>);
</div></code></pre>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>;
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'autorun:'</span>, store.x);
</div><div class="hljs-line">});
</div><div class="hljs-line">setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-comment">// 基于runInAction代替action修饰器「即便设置enforceActions配置项，它也是被允许的」，和action修饰器具备相同的效果！！</span>
</div><div class="hljs-line">    runInAction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">        store.x = <span class="hljs-number">1000</span>;
</div><div class="hljs-line">    });
</div><div class="hljs-line">}, <span class="hljs-number">1000</span>);
</div></code></pre>

    <p>实现异步派发</p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment">// 模拟从服务器获取数据</span>
</div><div class="hljs-line"><span class="hljs-keyword">const</span> query = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> {
</div><div class="hljs-line">        setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">            resolve(<span class="hljs-number">1000</span>);
</div><div class="hljs-line">        }, <span class="hljs-number">1000</span>);
</div><div class="hljs-line">    });
</div><div class="hljs-line">};
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    @observable x = <span class="hljs-number">10</span>
</div><div class="hljs-line">    @action.bound <span class="hljs-keyword">async</span> changeX() {
</div><div class="hljs-line">        <span class="hljs-keyword">let</span> res = <span class="hljs-number">0</span>;
</div><div class="hljs-line">        <span class="hljs-keyword">try</span> {
</div><div class="hljs-line">            res = <span class="hljs-keyword">await</span> query();
</div><div class="hljs-line">        } <span class="hljs-keyword">catch</span> (_) { }
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.x = res;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store;
</div><div class="hljs-line">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'autorun:'</span>, store.x);
</div><div class="hljs-line">});
</div><div class="hljs-line">store.changeX();
</div></code></pre>

    <h4 id="基于mobx重构taskoa案例">基于mobx重构TASKOA案例</h4>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line">结构目录
</div><div class="hljs-line">|- store
</div><div class="hljs-line">    |- TaskStore.js
</div><div class="hljs-line">    |- PersonalStore.js
</div><div class="hljs-line">    |- index.js
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">/*PersonalStore.js*/</span>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonalStore</span> </span>{
</div><div class="hljs-line">    <span class="hljs-keyword">constructor</span>(root) {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.root = root;
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> PersonalStore;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">/*TaskStore.js*/</span>
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, action, runInAction } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { getTaskList } <span class="hljs-keyword">from</span> <span class="hljs-string">'../api'</span>;
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskStore</span> </span>{
</div><div class="hljs-line">    <span class="hljs-keyword">constructor</span>(root) {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.root = root;
</div><div class="hljs-line">    }
</div><div class="hljs-line">    @observable taskList = <span class="hljs-literal">null</span>;
</div><div class="hljs-line">    <span class="hljs-comment">// 异步获取全部任务</span>
</div><div class="hljs-line">    @action.bound <span class="hljs-keyword">async</span> queryTaskListAction() {
</div><div class="hljs-line">        <span class="hljs-keyword">let</span> list = [];
</div><div class="hljs-line">        <span class="hljs-keyword">try</span> {
</div><div class="hljs-line">            <span class="hljs-keyword">let</span> result = <span class="hljs-keyword">await</span> getTaskList(<span class="hljs-number">0</span>);
</div><div class="hljs-line">            <span class="hljs-keyword">if</span> (+result.code === <span class="hljs-number">0</span>) {
</div><div class="hljs-line">                list = result.list;
</div><div class="hljs-line">            }
</div><div class="hljs-line">        } <span class="hljs-keyword">catch</span> (_) { }
</div><div class="hljs-line">        runInAction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">            <span class="hljs-keyword">this</span>.taskList = list;
</div><div class="hljs-line">        });
</div><div class="hljs-line">    }
</div><div class="hljs-line">    <span class="hljs-comment">// 同步删除某个任务</span>
</div><div class="hljs-line">    @action.bound removeTaskAction(id) {
</div><div class="hljs-line">        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">Array</span>.isArray(<span class="hljs-keyword">this</span>.taskList)) <span class="hljs-keyword">return</span>;
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.taskList = <span class="hljs-keyword">this</span>.taskList.filter(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
</div><div class="hljs-line">            <span class="hljs-keyword">return</span> +item.id !== +id;
</div><div class="hljs-line">        });
</div><div class="hljs-line">    }
</div><div class="hljs-line">    <span class="hljs-comment">// 同步修改某个任务</span>
</div><div class="hljs-line">    @action.bound updateTaskAction(id) {
</div><div class="hljs-line">        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">Array</span>.isArray(<span class="hljs-keyword">this</span>.taskList)) <span class="hljs-keyword">return</span>;
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.taskList = <span class="hljs-keyword">this</span>.taskList.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
</div><div class="hljs-line">            <span class="hljs-keyword">if</span> (+item.id === +id) {
</div><div class="hljs-line">                item.state = <span class="hljs-number">2</span>;
</div><div class="hljs-line">                item.complete = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleString(<span class="hljs-string">'zh-CN'</span>);
</div><div class="hljs-line">            }
</div><div class="hljs-line">            <span class="hljs-keyword">return</span> item;
</div><div class="hljs-line">        });
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> TaskStore;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">/*index.js*/</span>
</div><div class="hljs-line"><span class="hljs-keyword">import</span> TaskStore <span class="hljs-keyword">from</span> <span class="hljs-string">"./TaskStore"</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> PersonalStore <span class="hljs-keyword">from</span> <span class="hljs-string">"./PersonalStore"</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { configure } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line">configure({
</div><div class="hljs-line">    <span class="hljs-attr">enforceActions</span>: <span class="hljs-string">'observed'</span>
</div><div class="hljs-line">});
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
</div><div class="hljs-line">    <span class="hljs-keyword">constructor</span>() {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.task = <span class="hljs-keyword">new</span> TaskStore(<span class="hljs-keyword">this</span>);
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.personal = <span class="hljs-keyword">new</span> PersonalStore(<span class="hljs-keyword">this</span>);
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">new</span> Store();
</div></code></pre>

    <p>在组件中的使用</p>

    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment">/* index.jsx */</span>
</div><div class="hljs-line"><span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">'./store'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx-react'</span>;
</div><div class="hljs-line">...
</div><div class="hljs-line">root.render(
</div><div class="hljs-line">    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ConfigProvider</span> <span class="hljs-attr">locale</span>=<span class="hljs-string">{zhCN}</span>&gt;</span></span>
</div><div class="hljs-line"><span class="xml">        <span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> {<span class="hljs-attr">...store</span>}&gt;</span></span>
</div><div class="hljs-line"><span class="xml">            <span class="hljs-tag">&lt;<span class="hljs-name">Task</span> /&gt;</span></span>
</div><div class="hljs-line"><span class="xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
</div><div class="hljs-line"><span class="xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">ConfigProvider</span>&gt;</span></span>
</div><div class="hljs-line">);
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">/* Task.jsx */</span>
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { observer, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx-react'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">const</span> Task = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Task</span>(<span class="hljs-params">props</span>) </span>{
</div><div class="hljs-line">    <span class="hljs-comment">/* 获取TASK模块的Store实例 */</span>
</div><div class="hljs-line">    <span class="hljs-keyword">let</span> { task } = props;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">    <span class="hljs-comment">/* 关于TABLE和数据的处理 */</span>
</div><div class="hljs-line">    useEffect(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">        (<span class="hljs-keyword">async</span> () =&gt; {
</div><div class="hljs-line">            <span class="hljs-keyword">if</span> (!task.taskList) {
</div><div class="hljs-line">                setTableLoading(<span class="hljs-literal">true</span>);
</div><div class="hljs-line">                <span class="hljs-keyword">await</span> task.queryTaskListAction();
</div><div class="hljs-line">                setTableLoading(<span class="hljs-literal">false</span>);
</div><div class="hljs-line">            }
</div><div class="hljs-line">        })();
</div><div class="hljs-line">    }, []);
</div><div class="hljs-line">    useEffect(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line">        <span class="hljs-keyword">let</span> { taskList } = task;
</div><div class="hljs-line">        <span class="hljs-keyword">if</span> (!taskList) taskList = [];
</div><div class="hljs-line">        <span class="hljs-keyword">if</span> (selectedIndex !== <span class="hljs-number">0</span>) {
</div><div class="hljs-line">            taskList = taskList.filter(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
</div><div class="hljs-line">                <span class="hljs-keyword">return</span> +item.state === selectedIndex;
</div><div class="hljs-line">            });
</div><div class="hljs-line">        }
</div><div class="hljs-line">        setTableData(taskList);
</div><div class="hljs-line">    }, [selectedIndex, task.taskList]);
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">    ......
</div><div class="hljs-line">};
</div><div class="hljs-line"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> inject(<span class="hljs-string">'task'</span>)(observer(Task));
</div></code></pre>

    <h4 id="mobx6的应用">mobx6的应用</h4>

    <p>和mobx5的语法类似，只是去掉所有的装饰器，基于makeObservable、makeAutoObservable进行修饰处理即可！！</p>



    <pre class="prettyprint hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment">/*TaskStore.js*/</span>
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { observable, action, runInAction, makeObservable, makeAutoObservable } <span class="hljs-keyword">from</span> <span class="hljs-string">'mobx'</span>;
</div><div class="hljs-line"><span class="hljs-keyword">import</span> { getTaskList } <span class="hljs-keyword">from</span> <span class="hljs-string">'../api'</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskStore</span> </span>{
</div><div class="hljs-line">    <span class="hljs-keyword">constructor</span>(root) {
</div><div class="hljs-line">        <span class="hljs-keyword">this</span>.root = root;
</div><div class="hljs-line">        <span class="hljs-comment">/* // makeObservable函数可以捕获已经存在的对象属性并且使得它们可观察</span>
</div><div class="hljs-line"><span class="hljs-comment">        makeObservable(this, {</span>
</div><div class="hljs-line"><span class="hljs-comment">            taskList: observable,</span>
</div><div class="hljs-line"><span class="hljs-comment">            queryTaskListAction: action.bound,</span>
</div><div class="hljs-line"><span class="hljs-comment">            removeTaskAction: action.bound,</span>
</div><div class="hljs-line"><span class="hljs-comment">            updateTaskAction: action.bound</span>
</div><div class="hljs-line"><span class="hljs-comment">        }); */</span>
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line">        <span class="hljs-comment">/* </span>
</div><div class="hljs-line"><span class="hljs-comment">         makeAutoObservable 就像是加强版的 makeObservable，在默认情况下它将推断所有的属性</span>
</div><div class="hljs-line"><span class="hljs-comment">         推断规则：</span>
</div><div class="hljs-line"><span class="hljs-comment">            所有自有属性都成为 observable</span>
</div><div class="hljs-line"><span class="hljs-comment">            所有getters都成为 computed</span>
</div><div class="hljs-line"><span class="hljs-comment">            所有setters都成为 action</span>
</div><div class="hljs-line"><span class="hljs-comment">            所有prototype中的 functions 都成为 autoAction</span>
</div><div class="hljs-line"><span class="hljs-comment">            所有prototype中的 generator functions 都成为 flow</span>
</div><div class="hljs-line"><span class="hljs-comment">         */</span>
</div><div class="hljs-line">        makeAutoObservable(<span class="hljs-keyword">this</span>);
</div><div class="hljs-line">    }
</div><div class="hljs-line">    taskList = <span class="hljs-literal">null</span>;
</div><div class="hljs-line">    <span class="hljs-keyword">async</span> queryTaskListAction() {
</div><div class="hljs-line">       ...
</div><div class="hljs-line">    }
</div><div class="hljs-line">    removeTaskAction(id) {
</div><div class="hljs-line">        ...
</div><div class="hljs-line">    }
</div><div class="hljs-line">    updateTaskAction(id) {
</div><div class="hljs-line">        ...
</div><div class="hljs-line">    }
</div><div class="hljs-line">}
</div><div class="hljs-line"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> TaskStore;
</div></code></pre>
  </div>
</body>

</html>